home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl -w
- # $Id: mklists.pl,v 1.10 2000/12/14 13:09:57 ray Exp $
- #use strict;
-
- my $C = $0; $C =~ s%.*/%%;
-
- my $Mode = "create";
- my $Append = "";
- my $Help = 0;
- my $OptErr = "";
- my $debug = 0;
- my $missed = "MISSED";
- my %noMatch = (); # remember all patterns without a match
- my $quoteE = "";
- my $asterE = "";
- my $RetVal = 0;
-
- my %Default =
- (
- "dirs",
- [[ q:^\"/(bin|dev|etc|lib|sbin|usr|var)/\"$:, "IGNORED"],
- [ q:^\"/usr/(bin|doc|etc|games|include|info)/\"$:, "IGNORED"],
- [ q:^\"/usr/(lib|man|sbin|share|src)/\"$:, "IGNORED"],
- [ q:^\"/usr/share/(man|locale)/:, "IGNORED"],
- [ q:^\"/usr/share/(info|doc)/\"$:, "IGNORED"],
- [ q:^\"/var/(lib|lock|log|run|spool|state|tmp)/\"$:, "IGNORED"],
- [ q:^\"/usr/X11R6/:, "IGNORED"],
- [ q:^\"/opt/kde/:, "IGNORED"],
- # macro-based LSB/FHS directories
- [ q:^\"@Cprefix@/\"$:, "IGNORED"],
- [ q:^\"@LRdir@/\"$:, "IGNORED"],
- [ q:^\"@NKinetdir@/\"$:, "IGNORED"],
- [ q:^\"@SVIcdir@/\"$:, "IGNORED"],
- [ q:^\"@SVIdir@/\"$:, "IGNORED"],
- [ q:^\"@SVIrcd@/\"$:, "IGNORED"],
- # pre-LSB rules
- [ q:^\"/usr/man/man[123456789n]/\"$:, "IGNORED"],
- [ q:^\"/usr/include/:, "devel"],
- [ q:.*:, "base"],
- ],
- "files",
- [#[ q:/share/(locale|man)/(?>(?!(de|en|es|fr|it)/)):, "l10n"],
- [ q:/man[1456789n]/:, "base"],
- [ q:/man[23]/:, "devel"],
- [ q:^\"/usr/include:, "devel"],
- [ q:^\"(/usr)?/lib/.*\.so\"$:, "devel"],
- [ q:^\"(/usr)?/lib/.*\.la\"$:, "devel"],
- [ q:^\"(/usr)?/lib/.*\.a\"$:, "devel-static"],
- [ q:^\"\s*\"$:, "IGNORED"],
- [ q:^\"\#:, "IGNORED"],
- [ q:.*:, "base"],
- ]
- );
-
- ### functions
- sub compilePattern($@) {
- my( $mode, @default) = @_;
- my( @p2p) = ();
- my( $defattr) = "";
-
- if ( $Mode eq "dirs" ) {
- $Prefix = "%dir ";
- } else {
- $Prefix = "";
- }
-
- unshift(@ARGV, '-') if $#ARGV < $[;
- while ( <> ) {
- next if ( m:^\s*$: || m:^\s*\#: );
- print( STDERR "processing") if ( $debug );
- if ( s/^\*\s+\*\s+//o || s/^\@defattr\@\s*//io ) {
- # handle special line: set default attributes
- chomp($defattr = $_);
- } elsif ( s/^\*\s+(\S+)\s*$/$1/ || s/^\@(default).*$/$1/ ) {
- my $set = $1;
- die( "Sorry! Only 'default' supported for now!\n")
- unless ( $set eq "default" );
- print( STDERR " ruleset: '$set' ") if ( $debug );
- for ( $i = 0 ; $i <= $#default ; $i ++ ) {
- print( STDERR ".") if ( $debug );
- push( @p2p, [ @{$default[$i]} ]);
- }
- print( STDERR "\n") if ( $debug );
- } else {
- print( STDERR " rule...\n") if ( $debug );
-
- # split the pattern line:
- # first <pattern>,
- # second <target>,
- # third optional attributes
- my ( $patt, $targ, $attr) = split(' ', $_, 3);
- my $prefix = "";
-
- if ( $attr or $defattr) {
- my ( @attr) = ( split(/\s*,\s*/, $defattr), split(/\s*,\s*/, $attr) );
-
- foreach (@attr) {
- if ( m/prefix\((.*)\)/o) {
- if ($1) { $prefix .= " $1" } else { $prefix = "" };
- print( STDERR "prefix for '$patt' matches is '$prefix'\n")
- if ( $debug );
- } elsif ( m/mandatory/o) {
- print( STDERR "'$patt' is mandatory to match\n")
- if ( $debug );
- $noMatch{$patt} = 1;
- } elsif ( m/\!/o) {
- if ( defined( $noMatch{$patt}) ) {
- delete( $noMatch{$patt});
- print( STDERR "'$patt' is NOT mandatory to match\n")
- if ( $debug );
- } else {
- $noMatch{$patt} = 1;
- print( STDERR "'$patt' is mandatory to match\n")
- if ( $debug );
- }
- } else {
- print( STDERR "'$_' is not a known attribute, ignored\n")
- if ( $debug );
- }
- }
- $prefix =~ s/^ //;
- }
- push( @p2p, [ $patt, $targ, $prefix ]);
- }
- }
- # catch the rest...
- push( @p2p, [ ".*", $missed]);
-
- return ( @p2p );
- }
-
- sub listSubs(@) {
- my( @f ) = @_;
- my( %s) = ();
- my( $i, $j) = ( "", "");
- my( @b) = ();
-
- for $i ( 0 .. $#f ) {
- printf( STDERR "pkg='%s' pattern='%s'\n", $f[$i][1], $f[$i][0])
- if ( $debug );
- $s{$f[$i][1]} ++;
- }
-
- foreach $i ( sort( keys( %s)) ) {
- printf( STDERR "sub='%s': %d\n", $i, $s{$i}) if ( $debug >= 2 );
- next unless ( defined( $s{$i}) && $s{$i} > 0 );
- push( @b, $i) unless ( $i eq $j );
- $j = $i;
- }
- printf( STDERR "subs: '%s'\n", join( ', ', @b)) if ( $debug >= 1 );
- return ( @b );
- }
-
- sub match(\$) {
- my ( $t) = @_;
- my ( $i) = 0;
- my ( $patt, $out, $pref ) = undef;
- my $mc = 0;
-
- for ( $i=0; $i <= $#f2p ; $i++ ) {
- ( $patt, $out, $pref ) = @{$f2p[$i]};
- printf( STDERR "testing(%d): '%s'\n", $i, $patt) if ( $debug >= 9 );
- if ( $$t =~ m:$patt: ) {
- $mc ++;
- delete $noMatch{$patt} if ( defined( $noMatch{$patt}) );
- if ( $mc == 1 && $$t =~ /[ \t]/ ) {
- chomp( $$t);
- if ( $$t =~ /\*/ ) {
- $asterE .= " '$$t'\n";
- }
- if ( $$t =~ /\"/ ) {
- # rpm botches on those...
- $quoteE .= " '$$t'\n";
- next;
- }
- $$t = "\"" . $$t . "\"\n" if ( $$t =~ m:^/: );
- }
- $$t = "$pref $$t" if ( $pref );
- # continue the search for matching patterns for special queue '*'
- return $out unless ( $out eq '*' );
- }
- }
-
- printf( STDERR "Ouch: undefined: \$f2p[$i]\n") ;
- return( $missed );
- }
-
- ### parameter check
- while ( $#ARGV >= $[ && ($_ = shift, /^-/ || (unshift(@ARGV,$_) && 0)) ) {
- last if /^--$/;
- (/^--create$/ || /^-c$/) && ($Mode = "create", next);
- (/^--dirs$/ || /^-d$/) && ($Mode = "dirs", next);
- (/^--files$/ || /^-f$/) && ($Mode = "files", next);
- (/^--append$/ || /^-a$/) && ($Append = ">", next);
- (/^--debug$/ || /^-D$/) && ($debug ++, next);
- (/^--?help/ || /^-h/) && ($Help = 1, next);
- (/^-/) && ($OptErr .= "$_ ", next);
- }
-
- if ( $OptErr ) {
- printf( STDERR "$C: unkown option: $OptErr\n");
- }
-
- my $Pkg = shift;
-
-
- if ( $OptErr || $Help ) {
- die( "Usage: $C [-acdfh] pkg-name\n");
- }
-
- if ( "$Mode" eq "create" ) {
- my $D = $ENV{DESTDIR} || die( "$C: DESTDIR: no variable\n");
- system( "rm -f dirs-$Pkg files-$Pkg files-$Pkg-*" ) &&
- die( "$C: removing: $!\n");
- system( "find $D -type d -mindepth 1 -printf '\"/%P/\"\n' | sort > dirs-$Pkg") &&
- die( "$C: find dirs: $!\n");
- system( "find $D -not -type d -printf '\"/%P\"\n' | sort > files-$Pkg")
- &&
- die( "$C: find files: $!\n");
- exit( 0);
- }
-
- if ( ! -r "$Mode-$Pkg" ) {
- die( "$C: $Mode-$Pkg: $!\n");
- }
-
- my $i;
- local @f2p = compilePattern($Mode, @{$Default{$Mode}});
- my @subs = listSubs( @f2p);
-
- open( IN, "< $Mode-$Pkg" ) || die( "open('$Pkg'): $!\n");
- foreach $i ( @subs ) {
- printf( STDERR "open: >$Append files-$Pkg-$i\n") if ( $debug >= 2 );
- open( $i, ">$Append files-$Pkg-$i") || die( "open('$Pkg-$i'): $!\n");
- }
-
- while ( <IN> ) {
- my $out = match( $_);
- printf( STDERR "%-20s %s", "$out:", $_) if ( $debug >= 6 );
- print( $out $Prefix . $_);
- }
- close( IN);
-
- foreach $i ( @subs ) {
- close( $i);
- if ( -z "files-$Pkg-$i" ) {
- printf( STDERR "removing empty '%s'\n", "files-$Pkg-$i")
- if ( $debug >= 1 );
- unlink( "files-$Pkg-$i");
- }
- }
-
- if ( $asterE ) {
- print( STDERR "$C: warning: combination of whitespaces and '*' means" .
- " trouble:\n" . $asterE);
- }
- if ( $quoteE ) {
- print( STDERR "$C: Error: illegal combination of whitespace and ".
- "'\"':\n" . $quoteE);
- $RetVal++;
- }
- if ( %noMatch ) {
- print( STDERR "$C: Error: following manadatory patterns did not match:\n");
- foreach ( sort( keys( %noMatch)) ) {
- printf( STDERR " '%s'\n", $_ );
- }
- $RetVal++;
- }
- if ( -r "files-$Pkg-$missed" ) {
- printf( STDERR "$C: Error: non-empty safety net: files-$Pkg-$missed\n");
- $RetVal++;
- exit( 1);
- }
-
- exit( $RetVal);
-
-